package logic

import (
	"context"
	"encoding/json"
	"strconv"

	"demo/internal/errorx"
	"demo/internal/svc"
	"demo/internal/types"
	"demo/model"

	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/redis"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

type QuestionInfoLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
	rds *redis.Redis
	modelQ model.QuestionModel
	modelO model.OptionModel
	modelS model.ServeyModel
}

var ServeyDetailPrefix string = "servey:detail:id:"


func NewQuestionInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QuestionInfoLogic {
	rds,err := redis.NewRedis(redis.RedisConf{
		Host: svcCtx.Config.Redis.Host,
		Pass: svcCtx.Config.Redis.Pass,
		Type: svcCtx.Config.Redis.Type,
	})
	if err != nil {
		logx.Errorf("redis init error: %v", err)
	}
	return &QuestionInfoLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
		rds: rds,
		modelQ: model.NewQuestionModel(svcCtx.Orm),
		modelO: model.NewOptionModel(svcCtx.Orm),
		modelS: model.NewServeyModel(svcCtx.Orm,svcCtx.Config.Cache),
	}
}

// 获取问卷对应的信息包括问卷信息，问题信息
func (l *QuestionInfoLogic) QuestionInfo(req *types.QuestionInfoRequest) (resp *types.QuestionInfoResponse, err error) {
	// todo: add your logic here and delete this line
	var serveyResp types.ServeyItemResponse

	data,err := l.rds.GetCtx(l.ctx,QuestionDetailPrefix + strconv.FormatInt(req.ServeyId,10))
	if len(data) > 0 {
		var serveyInfo *types.ServeyItemResponse
		err = json.Unmarshal([]byte(data),&serveyInfo)
		if err != nil {
			return nil,err
		}
		l.rds.ExpireCtx(l.ctx,ServeyDetailPrefix + string(rune(req.ServeyId)),3600*2)
		return &types.QuestionInfoResponse{
			Code: 200,
			Msg: "search success",
			Data: *serveyInfo,
		},nil
	}
	err = l.modelS.Trans(l.ctx,func(context context.Context, session sqlx.Session) error {
		// 查询servey基本信息
		servey,err := l.modelS.FindOne(context,session,req.ServeyId)
		if err == sqlx.ErrNotFound || servey == nil || servey.IsDeleted == deleted {
			return errorx.NewBizError(500,"无该问卷信息")
		}
		// 查询下属的所有问题
		questions,err := l.modelQ.FindList(context,session,req.ServeyId)
		if err != nil {
			return err
		}
		options,err := l.modelO.FindList(context,session,req.ServeyId)
		if err != nil {
			return err
		}
		serveyResp = types.ServeyItemResponse{
			Id: servey.Id,
			CreatorId: servey.CreatorId,
			Title: servey.Title,
			Description: servey.Description,
			PublishTime: strconv.FormatInt(servey.PublishTime,10),
			CreateTime: strconv.FormatInt(servey.CreateTime,10),
			EndTime: strconv.FormatInt(servey.EndTime,10),
			IsPublic: servey.IsPublic,
			IsEnd: servey.IsEnd,
			VisitNum: servey.VisitNum,
		}
		sortedQuestions := make([]*types.QuestionItemResponse,0)
		for i := 0 ; i < len(questions) ; i++ {
			j := 0 
			if len(sortedQuestions) == 0{
				for j = 0 ; j < len(questions) ; j++ {
					if questions[j].QstSort == -1  {
						break;
					}
				}
			}else {
				lastQst := sortedQuestions[len(sortedQuestions) - 1]
				for j = 0 ; j < len(questions) ; j++ {
					if questions[j].QstSort == lastQst.Id {
						break;
					}
				}
			}
			sortedQuestions = append(sortedQuestions, &types.QuestionItemResponse{
				ServeyId: questions[j].ServeyId,
				QstContent: questions[j].QstContent,
				Id: questions[j].Id,
				Type: questions[j].Type,
				QstSort: questions[j].QstSort,
				IsMustAnswer: questions[j].IsMustAnswer,
				IsShow: questions[j].IsShow,

			})
		}
		for _,option  := range options {
			for i := 0 ; i < len(sortedQuestions) ; i++ {
				if option.QuestionId == sortedQuestions[i].Id {
					
					opt := &types.OptionalItemResponse{
						QuestionId: option.QuestionId,
						OpContent: option.OpContent,
						IsTrue: option.IsTrue,
						Id: option.Id,
					}
					sortedQuestions[i].Options = append(sortedQuestions[i].Options, opt)
					break;
				}
			}
		}
		serveyResp.QuestionList = sortedQuestions
		byteData,err := json.Marshal(serveyResp)
		if err != nil {
			return err
		}
		_,err = l.rds.SetnxExCtx(l.ctx,QuestionDetailPrefix + strconv.FormatInt(req.ServeyId,10),string(byteData),3600 * 2)
		return err
	})
	
	if err != nil {
		return nil,err
	}

	return &types.QuestionInfoResponse{
		Code: 200,
		Msg: "查询成功",
		Data: serveyResp,
	},nil
}
